package com.inspur.dgov.tenant.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.inspur.dgov.bsp.user.entity.PubUser;
import com.inspur.dgov.bsp.user.feign.IUserFeign;
import com.inspur.dgov.common.boot.operation.RedissonCollection;
import com.inspur.dgov.common.secure.dto.SecureUser;
import com.inspur.dgov.common.secure.utils.SecureUtil;
import com.inspur.dgov.common.tool.api.R;
import com.inspur.dgov.common.tool.constant.AppConstant;
import com.inspur.dgov.common.tool.utils.SMUtil;
import com.inspur.dgov.common.tool.utils.UniqueIdGenerator;
import com.inspur.dgov.tenant.entity.PubTenant;
import com.inspur.dgov.tenant.service.PubTenantService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 租户信息 前端控制器
 * </p>
 *
 * @author chiyupei
 * @since 2020-04-17
 */
@RestController
@RequestMapping("/tenant")
@Api(value = "租户信息管理", tags = "租户信息接口")
public class PubTenantController {

    @Autowired
    private PubTenantService pubTenantService;

    @Autowired
    private RedissonCollection redissonCollection;

    @Autowired
    private IUserFeign userFeign;

    /**
     * 租户信息列表
     */
    @PostMapping("/page")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "租户编码", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "name", value = "租户名称", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "regionId", value = "所属区划", paramType = "query", dataType = "string")
    })
    @ApiOperation(value = "租户信息列表", notes = "传入租户编码、名称或所属区划", position = 1)
    public R<IPage<PubTenant>> page(@ApiIgnore @RequestParam Map<String, Object> query, Page page) {
        IPage<PubTenant> pages = this.pubTenantService.selectTenantPage(page, query);
        return R.data(pages);
    }

    /**
     * 唯一性校验
     *
     * @param value
     * @param id
     * @return
     */
    @PostMapping("/verifyUnique")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "value", value = "租户编码", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "id", value = "租户ID", paramType = "query", dataType = "String")
    })
    @ApiOperation(value = "租户唯一性校验", notes = "传入租户编码和租户ID", position = 2)
    public R verifyUnique(@RequestParam(value = "value", required = true) String value,
                          @RequestParam(value = "id", required = false) String id) {
        if (StrUtil.hasEmpty(value)) {
            return R.fail("接口调用不合法");
        }

        QueryWrapper<PubTenant> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PubTenant::getCode, value);
        if (StrUtil.isNotEmpty(id)) {
            queryWrapper.lambda().ne(PubTenant::getId, id);
        }

        //查出满足条件的所有记录
        List<PubTenant> list = this.pubTenantService.list(queryWrapper);
        if (ObjectUtil.isEmpty(list)) {
            return R.success("");
        }
        return R.fail("该租户编码已被使用");
    }

    /**
     * 新增租户
     *
     * @param tenant
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "新增租户", notes = "传入租户信息", position = 3)
    public R add(@RequestBody PubTenant tenant) {
        SecureUser curUser = SecureUtil.getUser();
        LocalDateTime now = LocalDateTime.now();
        Long id = UniqueIdGenerator.generateId();
        tenant.setId(id);
        tenant.setCreator(Long.valueOf(curUser.getUserId()));
        tenant.setCreateTime(now);
        tenant.setStatus(AppConstant.DB_STATUS_NORMAL);
        boolean ret = this.pubTenantService.save(tenant);

        //创建租户管理员
        PubUser user = new PubUser();
        user.setId(UniqueIdGenerator.generateId());
        user.setAccount(tenant.getContactMobile());
        user.setName(tenant.getContact());
        user.setMobile(SMUtil.sm4Encrypt(tenant.getContactMobile()));
        user.setEmail(tenant.getContactEmail());
        user.setRegionId(tenant.getRegionId());
        user.setRegionName(tenant.getRegionName());
        user.setStatus(AppConstant.DB_STATUS_NORMAL);
        user.setTenantId(id);
        user.setCreator(Long.valueOf(curUser.getUserId()));
        user.setCreateTime(now);
        this.userFeign.addTenantSystemUser(user);

        //增加Redis中数据
        List<PubTenant> tenantRList = this.redissonCollection.getList(AppConstant.DEFAULT_TENANT_KEY);
        if (null != tenantRList) {
            tenantRList.add(tenant);
        } else {
            List<PubTenant> newList = new ArrayList<>();
            newList.add(tenant);
            this.redissonCollection.setListValues(AppConstant.DEFAULT_TENANT_KEY, newList, Long.valueOf(60 * 60 * 12 * 1000));
        }
        return R.status(ret);
    }

    /**
     * 更新租户
     *
     * @param tenant
     * @return
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新租户", notes = "传入租户信息", position = 4)
    public R update(@RequestBody PubTenant tenant) {
        SecureUser curUser = SecureUtil.getUser();
        LocalDateTime now = LocalDateTime.now();
        tenant.setUpdator(Long.valueOf(curUser.getUserId()));
        tenant.setUpdateTime(now);
        boolean ret = this.pubTenantService.updateById(tenant);

        //TODO 更新租户管理员

        //更新Redis数据
        List<PubTenant> tenantRList = this.redissonCollection.getList(AppConstant.DEFAULT_TENANT_KEY);
        if (null != tenantRList && tenantRList.size() > 0) {
            tenantRList.removeIf(item -> item.getId().equals(tenant.getId()));
            tenantRList.add(tenant);
        }
        return R.status(ret);
    }

    /**
     * 删除租户(假删除)
     */
    @PostMapping("/remove")
    @ApiOperation(value = "删除租户", notes = "传入租户信息", position = 5)
    public R remove(@RequestBody PubTenant tenant) {
        SecureUser curUser = SecureUtil.getUser();
        LocalDateTime now = LocalDateTime.now();
        tenant.setUpdator(Long.valueOf(curUser.getUserId()));
        tenant.setUpdateTime(now);
        tenant.setStatus(AppConstant.DB_STATUS_ABNORMAL);
        boolean ret = this.pubTenantService.updateById(tenant);
        //删除Redis中数据
        List<PubTenant> tenantRList = this.redissonCollection.getList(AppConstant.DEFAULT_TENANT_KEY);
        if (null != tenantRList && tenantRList.size() > 0) {
            tenantRList.removeIf(item -> item.getId().equals(tenant.getId()));
        }
        return R.status(ret);
    }
}
